package top.yongyan0624.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import top.yongyan0624.common.lang.CodeMsg;
import top.yongyan0624.common.lang.ResultVO;
import top.yongyan0624.entity.*;
import top.yongyan0624.service.SysRoleService;
import top.yongyan0624.service.SysUserRoleService;
import top.yongyan0624.service.SysUserService;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 讽惘
 * @since 2021-05-13
 */
@RestController
public class SysRoleController extends BaseController {

    @PreAuthorize("hasRole('superAdmin')")
    @Transactional
    @RequestMapping("/admin/addRole")
    public ResultVO addRole(@RequestBody SysRole sysRole) {
        if (sysRole.getName() == null || sysRole.getCode() == null || sysRole.getPriority() == null) {
            return ResultVO.error(new CodeMsg("角色名、角色代号、角色优先级不能为空！"));
        }

        SysRole role = sysRoleService.getOne(new QueryWrapper<SysRole>().eq("name", sysRole.getName()));
        if (role != null) {
            return ResultVO.error(new CodeMsg("新增失败！角色已经存在！"));
        }

        role = sysRoleService.getOne(new QueryWrapper<SysRole>().eq("code", sysRole.getCode()));
        if (role != null) {
            return ResultVO.error(new CodeMsg("新增失败！角色代号已重复！"));
        }

        boolean ok = sysRoleService.save(sysRole);

        if (ok) {
            return ResultVO.success("新增成功！");
        }

        return ResultVO.error(new CodeMsg("对不起！出错了，新增失败！"));
    }

    @PreAuthorize("hasRole('superAdmin')")
    @Transactional
    @PostMapping("/admin/updateRole")
    public ResultVO updateRole(@RequestBody SysRole sysRole) {
        if (sysRole.getName() == null || sysRole.getCode() == null || sysRole.getPriority() == null) {
            return ResultVO.error(new CodeMsg("角色名、角色代号、角色优先级不能为空！"));
        }

        SysRole role = sysRoleService.getOne(new QueryWrapper<SysRole>().eq("name", sysRole.getName()));
        if (role != null && !role.getId().equals(sysRole.getId())) {
            return ResultVO.error(new CodeMsg("修改失败！角色已经存在！"));
        }

        role = sysRoleService.getOne(new QueryWrapper<SysRole>().eq("code", sysRole.getCode()));
        if (role != null && !role.getId().equals(sysRole.getId())) {
            return ResultVO.error(new CodeMsg("修改失败！角色代号已重复！"));
        }

        boolean ok = sysRoleService.updateById(sysRole);
        // 更新缓存
        sysUserService.clearUserAuthorityInfoByRoleId(sysRole.getId());

        if (ok) {
            return ResultVO.success("修改成功！");
        }

        return ResultVO.error(new CodeMsg("对不起！出错了，修改失败！"));
    }

    @PreAuthorize("hasRole('superAdmin')")
    @Transactional
    @PostMapping("/admin/delRole/{id}")
    public ResultVO delRole(@PathVariable Long id) {
        boolean ok = sysRoleService.removeById(id);

        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("role_id", id));
        //清除权限缓存
        sysUserService.clearUserAuthorityInfoByRoleId(id);

        if (ok) {
            return ResultVO.success("删除成功！");
        }

        return ResultVO.error(new CodeMsg("对不起！出错了，删除失败！"));
    }

    @PreAuthorize("hasRole('superAdmin')")
    @Transactional
    @RequestMapping("/admin/delAllRole")
    public ResultVO delAllRole(@RequestBody MyList<Long> myList) {
        List<Long> ids = myList.getList();
        for (Long id : ids) {
            if (delRole(id).getCode() == 400) {
                return ResultVO.error(new CodeMsg("对不起！不存在这个角色:" + id + "，删除失败！"));
            }
        }
        // 删除中间表
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id", ids));
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id", ids));

        // 缓存同步删除
        ids.forEach(id -> {
            // 更新缓存
            sysUserService.clearUserAuthorityInfoByRoleId(id);
        });

        return ResultVO.success("删除成功！");
    }

    @PreAuthorize("hasAnyRole('admin','superAdmin')")
    @RequestMapping("/admin/queryRole")
    public ResultVO queryRole(@RequestParam Long pageNum, @RequestParam Long pageSize) {
        Page<SysRole> page = new Page<>(pageNum, pageSize);
        Page<SysRole> pageData = sysRoleService.page(page, new QueryWrapper<SysRole>().orderByAsc("priority"));

        return ResultVO.success(pageData);
    }

    @PreAuthorize("hasAnyRole('admin','superAdmin')")
    @RequestMapping("/admin/queryRoleByName")
    public ResultVO queryRoleByName(@RequestParam String name, @RequestParam Long pageNum, @RequestParam Long pageSize) {
        Page<SysRole> page = new Page<>(pageNum, pageSize);
        Page<SysRole> pageData = sysRoleService.page(page, new QueryWrapper<SysRole>()
                .like(name != null && !name.equals(""), "name", name)
                .orderByAsc("priority"));

        return ResultVO.success(pageData);
    }

    @PreAuthorize("hasAuthority('sys:role:list')")
    @GetMapping("/admin/role/info/{id}")
    public ResultVO info(@PathVariable("id") Long id) {
        SysRole sysRole = sysRoleService.getById(id);
        if (sysRole == null) {
            return ResultVO.error(new CodeMsg(400, "该角色不存在"));
        }
        // 获取角色相关联的菜单id
        List<SysRoleMenu> roleMenus = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id", id));
        List<Long> menuIds = roleMenus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
        sysRole.setMenuIds(menuIds);
        return ResultVO.success(sysRole);
    }

    @Transactional
    @PostMapping("/admin/role/menu/{roleId}")
    @PreAuthorize("hasAuthority('sys:role:perm')")
    public ResultVO perm(@PathVariable("roleId") Long roleId, @RequestBody Long[] menuIds) {

        List<SysRoleMenu> sysRoleMenus = new ArrayList<>();

        Arrays.stream(menuIds).forEach(menuId -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setMenuId(menuId);
            roleMenu.setRoleId(roleId);

            sysRoleMenus.add(roleMenu);
        });

        // 先删除原来的记录，再保存新的
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id", roleId));
        sysRoleMenuService.saveBatch(sysRoleMenus);

        // 删除缓存
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);

        return ResultVO.success("角色菜单设定成功", menuIds);
    }
}
